package com.zjuee.base.utils;

import com.zjuee.base.bean.response.CommonResultCode;
import com.zjuee.base.exception.BaseException;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.function.Function;

/**
 * @author wu liang
 * @since 2020/8/13 9:54
 */
public class CommonUtil {

    /**
     * 将id字符串转换为集合
     */
    public static Set<Integer> convertNumberSet(String ids) {
        Set<Integer> idList = new HashSet<>();
        if (StringUtils.isNotBlank(ids)) {
            String[] roleArr = ids.split("[,\\.，。 、]");
            for (String roleId : roleArr) {
                if (StringUtils.isBlank(roleId)) {
                    continue;
                }
                try {
                    idList.add(Integer.parseInt(roleId));
                } catch (NumberFormatException e) {
                    // id异常，掠过
                }
            }
        }
        return idList;
    }
    public static Set<Long> convertNumberSetLong(String ids) {
        Set<Long> idList = new HashSet<>();
        if (StringUtils.isNotBlank(ids)) {
            String[] roleArr = ids.split("[,\\.，。 、]");
            for (String roleId : roleArr) {
                if (StringUtils.isBlank(roleId)) {
                    continue;
                }
                try {
                    idList.add(Long.parseLong(roleId));
                } catch (NumberFormatException e) {
                    // id异常，掠过
                }
            }
        }
        return idList;
    }

    public static List<String> convertStringList(String ids) {
        List<String> idList = new ArrayList<>();
        if (StringUtils.isNotBlank(ids)) {
            String[] roleArr = ids.split("[,\\.，。 、]");
            for (String roleId : roleArr) {
                if (StringUtils.isBlank(roleId)) {
                    continue;
                }
                idList.add(roleId);
            }
        }
        return idList;
    }


    /**
     * 将数字转为指定长度的字符串，长度不够前边补0
     */
    public static String formatNumber(int number, int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append("0");
        }
        return sb.append(number).substring(sb.length() - length);
    }

    public static String getNextNumberStr(String numberStr, int length) {
        try {
            int number = Integer.parseInt(numberStr);
            return formatNumber(number + 1, length);
        } catch (Exception e) {
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "数字转化失败：" + numberStr);
        }
    }


    /**
     * Map 转 UrlPrams (a=11&b=22&c=33)
     */
    public static String map2ParamString(Map<String, Object> map) {
        if (map==null)
            return "";
        StringBuilder sb = new StringBuilder();
        for (String key : map.keySet()) {
            sb.append(key)
                    .append("=")
                    .append(Objects.toString(map.get(key), ""))
                    .append("&");
        }
        if (sb.length()>0)
            sb.setLength(sb.length() - 1);
        return sb.toString();
    }


    // region 抽取构建树结构的共用方法，适用所有基于levelCode结构来生成树的情况
    /**
     * 构建树结构
     */
    public static <E> List<E> buildTree(Collection<E> sources,
                                        Function<? super E, String> levelCodeMapper,
                                        Function<? super E, Collection<E>> childListMapper) {
        return buildTree(sources, levelCodeMapper, childListMapper, null);
    }
    /**
     * 构建树结构（反向设置父级资源）
     */
    public static <E> List<E> buildTree(Collection<E> sources,
                                        Function<? super E, String> levelCodeMapper,
                                        Function<? super E, Collection<E>> childListMapper,
                                        Function<String, E> getParentFunction) {
        List<E> result = new ArrayList<>();
        if (sources == null || sources.isEmpty())
            return result;

        for (E obj : sources) {
            String apply = levelCodeMapper.apply(obj);
            int level = apply.length() / 3;
            for (int i = 1; i <= level; i++) {
                //获取当前层levelCode
                String parentLevel = apply.substring(0, i * 3);
                buildTree(parentLevel, result, sources, levelCodeMapper, childListMapper, getParentFunction);
            }
        }
        return result;
    }

    // 递归生成树形结构
    public static <E> void buildTree(String levelCode, Collection<E> result, Collection<E> sources,
                                     Function<? super E, String> levelCodeMapper,
                                     Function<? super E, Collection<E>> childListMapper) {
        buildTree(levelCode, result, sources, levelCodeMapper, childListMapper, null);
    }

    // 递归生成树形结构(反向生成父级资源)
    public static <E> void buildTree(String levelCode, Collection<E> result, Collection<E> sources,
                                     Function<? super E, String> levelCodeMapper,
                                     Function<? super E, Collection<E>> childListMapper,
                                     Function<String, E> getParentFunction) {
        if (result == null)
            throw new BaseException(CommonResultCode.CONSUMER_ERR, "tree result can't be null");

        if (result.isEmpty()) {
            //先从查询结果中获取，减少查询次数
            for (E obj : sources) {
                if (levelCodeMapper.apply(obj).equals(levelCode)) {
                    result.add(obj);
                    return;
                }
            }

            // 结果集中没有查询到，查看是否反向设置父级资源
            if (getParentFunction != null) {
                E parent = getParentFunction.apply(levelCode);
                if (parent == null)
                    return;
                result.add(parent);
            }
        }
        // 不为空，遍历结果集
        else {
            boolean flag = true;
            for (E existObj : result) {
                if (existObj != null && levelCode.startsWith(levelCodeMapper.apply(existObj))) {
                    flag = false;
                    if (levelCode.length() == levelCodeMapper.apply(existObj).length()) {
                        break;
                    } else {
                        buildTree(levelCode, childListMapper.apply(existObj), sources, levelCodeMapper, childListMapper, getParentFunction);
                    }
                }
            }
            if (flag) {
                // 从查询结果中获取
                for (E obj : sources) {
                    if (levelCodeMapper.apply(obj).equals(levelCode)) {
                        result.add(obj);
                        return;
                    }
                }

                // 结果集中没有查询到，查看是否反向设置父级资源
                if (getParentFunction != null) {
                    E parent = getParentFunction.apply(levelCode);
                    if (parent == null)
                        return;
                    result.add(parent);
                }
            }
        }
    }

}

